package ua.edu.nuos.jeetraining2012.cms.util.mail;


import freemarker.template.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ua.edu.nuos.jeetraining2012.cms.entity.UserEntity;
import ua.edu.nuos.jeetraining2012.cms.service.User;
import ua.edu.nuos.jeetraining2012.cms.service.exception.ServiceValidationException;
import ua.edu.nuos.jeetraining2012.cms.util.LocaleWrapper;

import javax.mail.internet.InternetAddress;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.validation.ConstraintViolation;
import javax.validation.ValidatorFactory;
import java.io.UnsupportedEncodingException;
import java.util.*;

abstract public class UserAbstract implements Sendable {

    /**
     * Define logger
     */
    final protected Logger logger = LoggerFactory.getLogger(getClass());
    protected ValidatorFactory validatorFactory;
    protected UserEntity userEntity;
    protected User userService;

    @Override
    public List<InternetAddress> getRecipientList() {
        List<InternetAddress> list = new ArrayList<>();
        try {
            list.add(createInternetAddress(userEntity.getEmail(), userEntity.getName()));
        } catch (UnsupportedEncodingException e) {
            logger.error("getRecipient() - can't create InternetAddress", e);
        }
        return list;
    }

    @Override
    public List<InternetAddress> getCCList() {
        return new LinkedList();
    }

    @Override
    public List<InternetAddress> getBCCList() {
        return new LinkedList();
    }

    protected UserAbstract() {
        try {
            InitialContext ic = new InitialContext();
            validatorFactory = (ValidatorFactory) ic.lookup("java:comp/ValidatorFactory");
            userService      = (User)             ic.lookup("java:module/User");
        } catch (NamingException e) {
            logger.error("Can't create initial context", e);
        }
    }

    /**
     * Set user dto to be used in mail delivery
     *
     * @param user to be used for mail delivering
     * @throws ua.edu.nuos.jeetraining2012.cms.service.exception.ServiceValidationException
     *                                  When UserEntity values are invalid
     * @throws IllegalArgumentException When UserEntity is null
     */
    public void setUser(UserEntity user) throws ServiceValidationException {
        if (user == null) {
            throw new IllegalArgumentException("DTO can't be null");
        }
        Set<ConstraintViolation<UserEntity>> validationResult = validatorFactory.getValidator().validate(user);
        if (!validationResult.isEmpty()) {
            throw new ServiceValidationException(validationResult);
        }
        this.userEntity = user;
    }

    /**
     * Return InternetAddress object instantiated with supplied email and name
     *
     * @param email part of InternetAddress
     * @param name  part of InternetAddress
     * @return InternetAddress object
     * @throws UnsupportedEncodingException
     */
    protected InternetAddress createInternetAddress(String email, String name) throws UnsupportedEncodingException {
        return new InternetAddress(email, name);
    }

    /**
     * Return ResourceBundle which contains i18n used in mail
     *
     * @return resource bundle
     * @throws java.util.MissingResourceException
     *          if resource file not found
     */
    protected ResourceBundle getResourceBundle() {
        return LocaleWrapper.getBundle("mail");
    }

    /**
     * Return Template Configuration object
     *
     * @return Configuration return template configuration object
     */
    protected Configuration getTemplateConfig() {
        Configuration cfg = new Configuration();
        cfg.setClassForTemplateLoading(getClass(), "/templates/mail");
        return cfg;
    }
}
